package com.sc.nft.admin.consume;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.google.common.collect.Lists;
import com.sc.nft.dao.AutoUserListDao;
import com.sc.nft.dao.CollectionLowestPriceDao;
import com.sc.nft.dao.UserInfoDao;
import com.sc.nft.entity.*;
import com.sc.nft.entity.dto.NewSecondCollectionLockOrder;
import com.sc.nft.entity.dto.NewSecondCollectionPayDTO;
import com.sc.nft.entity.vo.GetPaySignVO;
import com.sc.nft.entity.vo.LockOrderVO;
import com.sc.nft.enums.*;
import com.sc.nft.exception.ModelException;
import com.sc.nft.service.NewSecondCollectionCommonService;
import com.sc.nft.service.PayOrderService;
import com.sc.nft.sup.ErrorCode;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.spring.annotation.RocketMQMessageListener;
import org.apache.rocketmq.spring.core.RocketMQListener;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

@RocketMQMessageListener(topic = MessageTopic.FREE_MARKET_TOPIC + "${spring.profiles.active}", consumerGroup = MessageTopic.FREE_MARKET_TOPIC + "${spring.profiles.active}")
@Component
@Slf4j
@RequiredArgsConstructor
public class AutoBuyConsumer implements RocketMQListener<SecondCollection> {

    private final CollectionLowestPriceDao collectionLowestPriceDao;
    private final NewSecondCollectionCommonService newSecondCollectionCommonService;
    private final PayOrderService payOrderService;
    private final RedissonClient redissonClient;
    private final UserInfoDao userInfoDao;
    private final AutoUserListDao autoUserListDao;
    private final RedisTemplate redisTemplate;


    @Override
    public void onMessage(SecondCollection secondCollection) {
        if (secondCollection.getMarketType() != MarketTypeEnum.FREE_MARKET) {
            return;
        }
        if (secondCollection.getMarketType() != MarketTypeEnum.FREE_MARKET) {
            return;
        }
        String priceKey = RedisKeyEnum.FREE_MARKET_LOWEST_PRICE.getKey() + secondCollection.getCollectionId();
        Object o = redisTemplate.opsForValue().get(priceKey);
        if (ObjectUtil.isNull(o)) {
            redisTemplate.opsForValue().set(priceKey, secondCollection.getSalesPrice().setScale(2).toPlainString());
        } else {
            BigDecimal oldPrice = NumberUtil.toBigDecimal(String.valueOf(o));
            if (NumberUtil.isGreater(oldPrice, secondCollection.getSalesPrice())) {
                redisTemplate.opsForValue().set(priceKey, secondCollection.getSalesPrice().setScale(2).toPlainString());
            }
        }


        boolean exists = collectionLowestPriceDao.exists(secondCollection.getCollectionId(), secondCollection.getSalesPrice());
        if (!exists) {
            return;
        }
        NewSecondCollectionLockOrder newSecondCollectionLockOrder = new NewSecondCollectionLockOrder();
        newSecondCollectionLockOrder.setSecondCollectionIds(Lists.newArrayList(secondCollection.getId()));
        newSecondCollectionLockOrder.setCollectionId(secondCollection.getCollectionId());
        newSecondCollectionLockOrder.setMarketType(secondCollection.getMarketType());
        List<RLock> lock = new ArrayList();
        try {
            // 用来存放被锁的id
            List<Long> mallLockId = new ArrayList<>();
            newSecondCollectionLockOrder.getSecondCollectionIds().forEach(aLong -> {
                // lock的key组成  LOCK_ORDER挂售id
                String key = StrUtil.format("LOCK_ORDER:{}", aLong);
                RLock orderLock = redissonClient.getLock(key);
                log.info("二级锁单Key:{}", orderLock);
                boolean heldByCurrentThread = orderLock.tryLock();
                if (!heldByCurrentThread) {
                    // 把挂载的商品id返回去.
                    mallLockId.add(aLong);
                } else {
                    lock.add(orderLock);
                }
            });
            if (CollUtil.isNotEmpty(mallLockId)) {
                throw new ModelException(mallLockId, ErrorCode.COUNT_NOT_ENOUGH);
            }
            log.info("锁单入参请求参数:{}", JSON.toJSON(newSecondCollectionLockOrder));
            UserInfo userInfo = userInfoDao.getById(autoUserListDao.getRandomOne().getUserId());
            LockOrderVO lockOrderVO = newSecondCollectionCommonService.lockOrder(userInfo, newSecondCollectionLockOrder);
            GetPaySignVO paySecond = payOrderService.getPaySecond(PayMethodEnum.WALLET_PAY, lockOrderVO.getOrderIds(),
                    null, userInfo, "127.0.0.1", null, false, null, null);
            payOrderService.verifyPay(userInfo, paySecond.getId(), userInfo.getTransactionPassword(), null, null);
        } catch (Exception e) {
            //就抢一次 留一线生机
            log.warn("没抢到：", e);
        } finally {
            // 批量释放锁
            lock.forEach(rLock -> {
                rLock.unlock();
                log.info("二级释放Key:{}", rLock);
            });
        }
    }
}
